"""
Обработчик событий внутриигрового мира Чио.
Скрипт НЕ работает!

Author: Milinuri Nirvalen
Ver: 0.3 (4)
"""

from backends.vk import VkGroup
from chiori import Chio
from chiori import Config
from chiori import Logger
from chiori import fcheck
from libs.game import Profile

import asyncio
import os
import time

from loguru import logger


# Настройки Кардинала
# ===================

main_chat = 7
peer_id = "2000000007"
chat_name = "【sʟ】"
base_status = "sᴀʟᴏʀʟᴀɴᴅ"
profiles_folder = "data/profiles"

b = VkGroup(Chio())

main_model = {
	"date":[0, 0, 0, 0, 0], "last_update":[0, 0, 0, 0, 0],
	"price":0, "last_price":0, "p_multiplier":1
}


# Вспомогательные классы
# ======================

class Date:
	"""Класс работы с игровым временем."""

	def __init__(self, date: list[int]) -> None:
		super(Date, self).__init__()
		self.date = date
		self.update_params()

	def update_params(self) -> None:
		"""Обновляет аттрибуты класса."""
		self.years = self.date[0]
		self.month = self.date[1]
		self.days = self.date[2]
		self.hours = self.date[3]
		self.minutes = self.date[4]

		self.total_month = self.date[1] + self.date[0]*15
		self.total_days = self.date[2] + self.total_month*30
		self.total_hours = self.date[3] + self.total_days*25
		self.total_minutes = self.date[4] + self.total_hours*50

	def time_shift(self, i: int, index: int, step: int) -> None:
		"""Сдвигает переполненные значения времени вправо."""
		self.sdate[index-1] += i // step
		self.sdate[index] = i % step

	def add_(self, *, minute=0, hour=0, day=0, month=0, year=0) -> None:
		"""Добавляет время в систему.

		Args:
		    minute (int, optional): Сколько минут
		    hour (int, optional): Сколько часов
		    day (int, optional): Сколько дней
		    month (int, optional): Сколько месяцев
		    year (int, optional): Сколько лет
		"""
		if minute:
			self.date[4] += minute
		if hour:
			self.date[3] += hour
		if day:
			self.date[2] += day
		if month:
			self.date[1] += month
		if year:
			self.date[0] += year

		self.time_shift(self.date[4], 4, 50)
		self.time_shift(self.date[3], 3, 25)
		self.time_shift(self.date[2], 2, 30)
		self.time_shift(self.date[1], 1, 12)
		self.update_params()


class Cardinal:
	"""Клсс автономной системы управления внутреигровым миром."""

	def __init__(self) -> None:
		super(Cardinal, self).__init__()
		self.data = Config(None, main_model, "data/game.toml")
		fcheck("data/profiles/", True)


	# Описание событий
	# ================

	async def new_day_event(self, date: list[int]) -> None:
		"""Отправляет сообщение с новостной сводкой каждый день.

		Args:
		    date (list[int]): Описание
		"""
		logger.info("Start new_day_event...")
		str_date = f"{date[2]}.{date[1]}.{date[0]}"
		text = f"Доброе утро!\n Сегодня {str_date}."
		await b.request("messages.editChat",
			chat_id=main_chat, title=chat_name+str_date
		)
		await b.message(None, text, peer_id=peer_id)
		logger.info("Finished new_day_event")


	# Описание обновлений
	# ===================

	async def minute_update(self):
		"""Ежеменутные обновления."""
		pass

	async def hour_update(self):
		"""Ежечасные обновления."""
		logger.info("Start hour update...")
		ids = [x.split('.')[0] for x in os.listdir(profiles_folder)]

		for x in ids:
			pr = Profile(x)

			if pr.max_hp != pr.hp:
				if pr.hp+pr.hp_regen < pr.max_hp:
					pr.profile.file_data["chars"]["hp"] += pr.hp_regen
				else:
					pr.profile.file_data["chars"]["hp"] = pr.max_hp

				logger.info("{}: {}HP (+{}HP)",
					x, pr.profile.file_data["chars"]["hp"], pr.hp_regen
				)

			if pr.max_mana != pr.mana:
				if pr.mana+pr.mana_regen < pr.max_mana:
					pr.profile.file_data["chars"]["mana"] += pr.mana_regen
				else:
					pr.profile.file_data["chars"]['mana'] = pr.max_mana

				logger.info("{}: {}MP (+{}MP)",
					x, pr.profile.file_data["chars"]["mana"], pr.mana_regen
				)
		logger.info("Finished hour update")

	async def month_update(self):
		"""Ежемесячные обновления."""
		logger.info("Start month update...")
		old_pm = self.data.file_data["p_multiplier"]

		if self.data.file_data["date"][1] in [12, 1, 2]:
			pm = 2
		if self.data.file_data["date"][1] in [3, 4, 5]:
			pm = 1.5
		if self.data.file_data["date"][1] in [6, 7, 8]:
			pm = 1
		if self.data.file_data["date"][1] in [9, 10, 11]:
			pm = 1.75

		self.data.file_data["p_multiplier"] = pm
		logger.info("Price multiplier: {} -> {}", old_pm, pm)
		logger.info("Finished month update")

	async def year_update(self):
		"""Ежегодные обновления."""
		pass


	async def update(self):
		self.data = Config(None, main_model, "data/game.toml")

		d = Date(self.data.file_data["date"])
		ud = Date(self.data.file_data["last_update"])

		d.add_(minute=1)
		logger.info("time: {}", d.date)
		self.data.file_data["date"] = d.date

		if d.years > ud.years:
			await self.year_update()

		if d.total_month > ud.total_month:
			await self.month_update()

		if d.total_days > ud.total_days:
			await self.new_day_event(self.data.file_data["date"])

		if d.total_hours > ud.total_hours:
			await self.hour_update()

		if d.total_minutes > ud.total_minutes:
			await self.minute_update()

		self.data.file_data["last_update"] = d.date
		self.data.save()
		logger.info("Update Finished")


# Запуск системы
# ==============

if __name__ == '__main__':
	app = Cardinal()
	while True:
		try:
			asyncio.run(app.update())
			time.sleep(5)
		except Exception as e:
			logger.exception(e)
